<template>
    <div>
        <div class="label">
            <div>组织架构</div>
            <ul>
                <li>
                    <el-tooltip class="item" effect="dark" content="刷新" placement="bottom-start">
                        <i @click="getDeptList" class="el-icon-refresh"></i>
                    </el-tooltip>
                </li>
                <li @click="draggable=true">
                    <el-tooltip class="item" effect="dark" content="拖动排序" placement="bottom">
                        <i class="el-icon-s-operation"></i>
                    </el-tooltip>
                </li>
                <li v-if="draggable" class="no">
                    <el-button @click="handleOrderDeptList" type="text" size="mini">保存</el-button>
                    <el-button @click="draggable=false" type="text" size="mini">取消</el-button>
                </li>
            </ul>
        </div>
        <div class="container">
            <el-tree
                    @node-click="deptClick"
                    @node-contextmenu="deptContextmenu"
                    ref="deptTree"
                    node-key="id"
                    :default-expand-all="true"
                    :expand-on-click-node="false"
                    :check-on-click-node="true"
                    :draggable="draggable"
                    :data="deptTree"
                    :props="props">
                <span class="el-tree-node__label" slot-scope="{ node, data }" style="width: 85%;" :class="{'selected': department.departmentId === data.id}">
                    <span>{{ node.label }}</span>
                    <svg-icon style="float: right" v-if="department.departmentId === data.id" icon-class="icon-star"></svg-icon>
                </span>
            </el-tree>
        </div>
        <v-contextmenu ref="contextmenu" class="tree-context-menu">
            <v-contextmenu-item @click="handleAddDept">
                <span>新增</span>
                <i class="el-icon-plus"></i>
            </v-contextmenu-item>
            <v-contextmenu-item @click="handleUpdateDept">
                <span>编辑</span>
                <i class="el-icon-edit"></i>
            </v-contextmenu-item>
            <v-contextmenu-item v-if="deleteable" @click="handleDeleteDept">
                <span>删除</span>
                <i class="el-icon-delete"></i>
            </v-contextmenu-item>
            <v-contextmenu-item>
                <span>新增成员</span>
                <i class="el-icon-user"></i>
            </v-contextmenu-item>
        </v-contextmenu>
        <form-dialog
                :title="addable?'新增部门':'编辑部门'"
                :visible="addable || updateable"
                @submit="submit"
                @close="addable=updateable=false">
            <Form ref="deptForm" :form="dataForm"></Form>
        </form-dialog>
    </div>
</template>

<script>
    import { getTree } from '../../../utils/tree';
    import FormDialog from '../../../components/formDialog.vue'
    import Form from './form'

    let events = {
        CLICK: 'click'
    }

    export default {
        props: {
            department: {
                type: Object,
                default() {
                    return {
                        departmentId: "1",
                        departmentName: null,
                        departmentIds: "1"
                    }
                }
            }
        },
        components: {
            FormDialog,
            Form
        },
        data() {
            return {
                draggable: false,
                addable: false,
                updateable: false,
                deleteable: true,
                fullscreen: false,

                deptList: [],
                deptTree: [],
                props: {
                    children: 'children',
                    label: 'name'
                },
                // 传递的数据Form表单
                dataForm: {},
                // 缓存用Form表单
                tempForm: {}
            }
        },
        created() {
            this.getDeptList()
        },
        methods: {
            getDeptList() {
                this.$service.system.dept.list().then((res)=> {
                    this.deptList = res || []
                    this.deptTree = getTree(this.deptList)
                })
            },
            addDept(form) {
                let addForm = this.$clone(form)
                this.$service.system.dept.add(addForm).then((res) => {
                    this.dataForm = {}
                    this.tempForm = {}
                    this.addable = false
                    this.updateable = false
                    this.getDeptList()
                })
            },
            updateDept(form) {
                let updateForm = this.$clone(form)
                this.$service.system.dept.update(updateForm).then((res) => {
                    this.dataForm = {}
                    this.tempForm = {}
                    this.addable = false
                    this.updateable = false
                    this.getDeptList()
                })
            },
            deleteDept(form) {
                let deleteFrom = this.$clone(form)
                this.$service.system.dept.delete(deleteFrom).then((res) => {
                    this.dataForm = {}
                    this.tempForm = {}
                    this.deleteable = false
                    this.getDeptList()
                    if (!deleteFrom.deleteUser) {
                        this.$alert('该部门用户已移动到部门顶级', '删除成功', {
                            confirmButtonText: '确定'
                        });
                    }
                })
            },
            orderDeptList(deptList) {
                this.$service.system.dept.order(deptList).then((res) => {
                    this.draggable = false
                    this.getDeptList()
                })
            },
            handleOrderDeptList() {
                this.$confirm('部门架构已发生改变，是否保存？', '提示', {
                    confirmButtonText: '确定',
                    cancelButtonText: '取消',
                    type: 'warning'
                }).then(() => {
                    // 设置选中第一个父节点,并自动选中子节点
                    this.$refs.deptTree.setChecked(this.deptTree[0].id, true, true)
                    // 获取所有选中节点
                    let allNodes = this.$refs.deptTree.getCheckedNodes()
                    let deptMap = {}
                    // 数据中包含的parentId是原本不变的信息，只能通过children来重新赋值parentId
                    let orderNums = {}
                    allNodes.forEach((d) => {
                        deptMap[d.id] = {
                            id: d.id,
                            parentId: null
                        }
                        orderNums[d.id] = 0
                    })
                    allNodes.forEach((d) => {
                        if (d.children) {
                            d.children.forEach((dc) => {
                                deptMap[dc.id].parentId = d.id
                                let nextNum = orderNums[d.id] + 1
                                deptMap[dc.id].orderNum = nextNum
                                orderNums[d.id] = nextNum
                            })
                        }
                    })
                    this.orderDeptList(Object.values(deptMap))
                }).catch(() => {
                });
            },
            deptClick(object, value, element) {
                this.department.departmentId = object.id
                this.department.departmentName = object.name
                this.$refs.contextmenu.hide()
                let departmentIds = this.$refs.deptTree.getCheckedNodes(false).map(e=>e.id)
                this.$refs.deptTree.setCheckedNodes([])
                this.department.departmentIds = departmentIds.join(',')
                this.$emit(events.CLICK, departmentIds)
            },
            deptContextmenu(event, object, value, element) {
                this.department.departmentId = object.id
                this.department.departmentName = object.name
                this.tempForm = this.$clone(object)
                this.deleteable = !!object.parentId
                this.$refs.contextmenu.show({
                    top: event.y,
                    left: event.x
                })
            },
            getNextOrderNum(parentId) {
                let parentNode = this.$refs.deptTree.getNode(parentId)
                let childOrderNums = parentNode.childNodes.map(e=>e.data.orderNum).sort().reverse()
                return childOrderNums.length > 0 ? childOrderNums[0] + 1 : 0
            },
            handleAddDept() {
                this.dataForm = {
                    parentId: this.tempForm.id,
                    parentName: this.tempForm.name,
                    orderNum: this.getNextOrderNum(this.tempForm.id)
                }
                this.addable = true
                this.updateable = false
            },
            handleUpdateDept() {
                this.dataForm = {
                    id: this.tempForm.id,
                    name: this.tempForm.name,
                    parentId: this.tempForm.parentId,
                    parentName: this.tempForm.parentName,
                    orderNum: this.tempForm.orderNum
                }
                this.addable = false
                this.updateable = true
            },
            handleDeleteDept() {
                this.$confirm('该操作会删除部门下的所有用户，是否确认？', '提示', {
                    confirmButtonText: '直接删除',
                    cancelButtonText: '保留用户',
                    type: 'warning'
                }).then(() => {
                    this.deleteDept({
                        deleteUser: true,
                        ids: this.tempForm.id
                    })
                }).catch(() => {
                    this.deleteDept({
                        deleteUser: false,
                        ids: this.tempForm.id
                    })
                });
            },
            submit() {
                this.$refs.deptForm.validate((flag) => {
                    if (flag) {
                        if (this.addable && !this.updateable) {
                            this.addDept(this.dataForm)
                        } else if (!this.addable && this.updateable) {
                            this.updateDept(this.dataForm)
                        }
                    }
                })
            }
        }
    };
</script>

<style lang="scss" scoped>

    .el-tree-node__content :not(.selected) {
        background-color: #F5F7FA!important;
    }
</style>
